package com.snow.java.base.junit;

import com.sun.deploy.security.ValidationState;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import static java.lang.annotation.ElementType.*;

/**
 * @类名称：
 * @类描述：
 * @author: bingHeng
 * @Date 2019.04.13
 * @Version: 1.0
*/

@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    /**
     * 重复注解与类型注解：
     *  Java 8对注解提供了两点改进：可重复的注解以及可用于类型的注解
     *
     *  要想定义重复注解必须使用@Reteatable注解修饰该类
     */

    String value() default "my name is Tom";
}


/**
 * @类名称：重复注解所需要的容器
 * @类描述：
 * @author: bingHeng
 * @Date 2019.04.13
 * @Version: 1.0
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotations {

    MyAnnotation[] value();

}

/**
 * @类名称：测试重复注解
 * @类描述：
 * @author: bingHeng
 * @Date 2019.04.13
 * @Version: 1.0
*/
class TestMyAnnotation {

    @MyAnnotation("Hello")
    @MyAnnotation("World")
    public void show(@MyAnnotation("abc")String str) {

    }

    public static void main(String[] args) throws NoSuchMethodException {

        // 反射获取
        Class<TestMyAnnotation> testMyAnnotationClass = TestMyAnnotation.class;

        // 反射获取多个注解修饰的方法
        Method show = testMyAnnotationClass.getMethod("show");

        // 反射获取注解类数组
        MyAnnotation[] declaredAnnotationsByType = show.getDeclaredAnnotationsByType(MyAnnotation.class);
        for(MyAnnotation myAnnotation : declaredAnnotationsByType) {
            System.out.println(myAnnotation.value());
        }
    }
}
